#!/bin/bash
# ============================================================================
# NFShmXFrame CI/CD 部署脚本
# ============================================================================
#
# 本脚本用于 CI/CD 流水线中的自动化部署
#
# 功能：
#   1. 部署到远程服务器
#   2. 备份现有版本
#   3. 停止和启动服务
#   4. 健康检查
#
# 使用方法：
#   ./ci/deploy.sh [环境] [主机]
#
# 环境变量：
#   DEPLOY_HOST    - 部署主机地址
#   DEPLOY_USER    - 部署用户
#   DEPLOY_DIR     - 部署目录
#   DEPLOY_ENV     - 部署环境（dev/test/prod）
#   SSH_KEY        - SSH 私钥路径
#
# ============================================================================

set -e
set -u

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 默认参数
DEPLOY_ENV=${1:-${DEPLOY_ENV:-dev}}
DEPLOY_HOST=${2:-${DEPLOY_HOST:-}}
DEPLOY_USER=${DEPLOY_USER:-deploy}
DEPLOY_DIR=${DEPLOY_DIR:-/opt/nfshm-xframe}
GAME_DIR=${GAME_DIR:-LieRen}
BUILD_TYPE=${BUILD_TYPE:-Dynamic_Release}
VERSION=${VERSION:-dev}
SSH_KEY=${SSH_KEY:-}
SSH_PORT=${SSH_PORT:-22}
RELEASE_PACKAGE=${RELEASE_PACKAGE:-}

log_info "=========================================="
log_info "NFShmXFrame CI/CD 部署脚本"
log_info "=========================================="
log_info "部署环境: ${DEPLOY_ENV}"
log_info "部署主机: ${DEPLOY_HOST}"
log_info "部署用户: ${DEPLOY_USER}"
log_info "部署目录: ${DEPLOY_DIR}"
log_info "游戏项目: ${GAME_DIR}"
log_info "版本: ${VERSION}"
log_info "=========================================="

# 检查参数
check_parameters() {
    if [ -z "${DEPLOY_HOST}" ]; then
        log_error "未指定部署主机地址"
        log_info "使用方法: $0 [环境] [主机]"
        log_info "或设置环境变量: DEPLOY_HOST=<主机地址>"
        exit 1
    fi
    
    # 检查 SSH 连接
    log_info "检查 SSH 连接..."
    local SSH_CMD="ssh -p ${SSH_PORT}"
    if [ -n "${SSH_KEY}" ]; then
        SSH_CMD="${SSH_CMD} -i ${SSH_KEY}"
    fi
    
    if ! ${SSH_CMD} -o ConnectTimeout=10 -o StrictHostKeyChecking=no "${DEPLOY_USER}@${DEPLOY_HOST}" "echo 'SSH connection OK'" > /dev/null 2>&1; then
        log_error "无法连接到部署主机: ${DEPLOY_HOST}"
        log_info "请检查 SSH 配置和网络连接"
        exit 1
    fi
    
    log_success "SSH 连接正常"
}

# 准备发布包
prepare_package() {
    log_info "准备发布包..."
    
    # 如果指定了发布包路径
    if [ -n "${RELEASE_PACKAGE}" ] && [ -f "${RELEASE_PACKAGE}" ]; then
        log_info "使用指定的发布包: ${RELEASE_PACKAGE}"
        return
    fi
    
    # 查找发布包
    local RELEASE_NAME="nfshm-xframe-${GAME_DIR}-${VERSION}"
    RELEASE_PACKAGE="release/${RELEASE_NAME}.tar.gz"
    
    if [ ! -f "${RELEASE_PACKAGE}" ]; then
        log_error "未找到发布包: ${RELEASE_PACKAGE}"
        log_info "请先运行 ci/package.sh 创建发布包"
        exit 1
    fi
    
    log_success "发布包: ${RELEASE_PACKAGE}"
}

# 上传发布包到服务器
upload_package() {
    log_info "上传发布包到服务器..."
    
    local SSH_CMD="ssh -p ${SSH_PORT}"
    local SCP_CMD="scp -P ${SSH_PORT}"
    
    if [ -n "${SSH_KEY}" ]; then
        SSH_CMD="${SSH_CMD} -i ${SSH_KEY}"
        SCP_CMD="${SCP_CMD} -i ${SSH_KEY}"
    fi
    
    # 创建临时目录
    local REMOTE_TMP_DIR="/tmp/nfshm-deploy-$(date +%Y%m%d_%H%M%S)"
    ${SSH_CMD} "${DEPLOY_USER}@${DEPLOY_HOST}" "mkdir -p ${REMOTE_TMP_DIR}"
    
    # 上传发布包
    log_info "上传中..."
    ${SCP_CMD} "${RELEASE_PACKAGE}" "${DEPLOY_USER}@${DEPLOY_HOST}:${REMOTE_TMP_DIR}/"
    
    # 上传校验和文件（如果存在）
    if [ -f "${RELEASE_PACKAGE}.sha256" ]; then
        ${SCP_CMD} "${RELEASE_PACKAGE}.sha256" "${DEPLOY_USER}@${DEPLOY_HOST}:${REMOTE_TMP_DIR}/"
    fi
    
    # 在服务器上验证校验和
    if [ -f "${RELEASE_PACKAGE}.sha256" ]; then
        log_info "验证校验和..."
        ${SSH_CMD} "${DEPLOY_USER}@${DEPLOY_HOST}" "cd ${REMOTE_TMP_DIR} && sha256sum -c $(basename ${RELEASE_PACKAGE}).sha256"
    fi
    
    log_success "发布包上传完成"
    
    # 保存临时目录路径
    echo "${REMOTE_TMP_DIR}" > /tmp/deploy_tmp_dir.txt
}

# 停止现有服务
stop_service() {
    log_info "停止现有服务..."
    
    local SSH_CMD="ssh -p ${SSH_PORT}"
    if [ -n "${SSH_KEY}" ]; then
        SSH_CMD="${SSH_CMD} -i ${SSH_KEY}"
    fi
    
    # 检查服务是否存在
    ${SSH_CMD} "${DEPLOY_USER}@${DEPLOY_HOST}" << 'STOP_EOF' || log_warning "停止服务失败或服务不存在"
if [ -f "${DEPLOY_DIR}/${DEPLOY_ENV}/NFPluginLoader" ]; then
    echo "停止服务..."
    cd "${DEPLOY_DIR}/${DEPLOY_ENV}"
    ./NFPluginLoader --Server=AllServer --ID=1.13.1.1 --Config=Config --Plugin=Plugin --Game=${GAME_DIR} --Stop || true
    sleep 3
    
    # 确认进程已停止
    if pgrep -f "NFPluginLoader.*${GAME_DIR}" > /dev/null; then
        echo "警告: 进程仍在运行，强制终止..."
        pkill -9 -f "NFPluginLoader.*${GAME_DIR}" || true
        sleep 1
    fi
    
    echo "服务已停止"
else
    echo "未找到现有服务"
fi
STOP_EOF

    log_success "服务停止完成"
}

# 备份现有版本
backup_current() {
    log_info "备份现有版本..."
    
    local SSH_CMD="ssh -p ${SSH_PORT}"
    if [ -n "${SSH_KEY}" ]; then
        SSH_CMD="${SSH_CMD} -i ${SSH_KEY}"
    fi
    
    ${SSH_CMD} "${DEPLOY_USER}@${DEPLOY_HOST}" << BACKUP_EOF
if [ -d "${DEPLOY_DIR}/${DEPLOY_ENV}" ]; then
    BACKUP_DIR="${DEPLOY_DIR}/${DEPLOY_ENV}.backup.$(date +%Y%m%d_%H%M%S)"
    echo "备份到: \${BACKUP_DIR}"
    sudo mv "${DEPLOY_DIR}/${DEPLOY_ENV}" "\${BACKUP_DIR}"
    
    # 保留最近 3 个备份
    echo "清理旧备份..."
    cd "${DEPLOY_DIR}"
    ls -dt ${DEPLOY_ENV}.backup.* 2>/dev/null | tail -n +4 | xargs -r sudo rm -rf
    
    echo "备份完成"
else
    echo "没有现有版本需要备份"
fi
BACKUP_EOF

    log_success "备份完成"
}

# 部署新版本
deploy_new_version() {
    log_info "部署新版本..."
    
    local SSH_CMD="ssh -p ${SSH_PORT}"
    if [ -n "${SSH_KEY}" ]; then
        SSH_CMD="${SSH_CMD} -i ${SSH_KEY}"
    fi
    
    local REMOTE_TMP_DIR=$(cat /tmp/deploy_tmp_dir.txt)
    local PACKAGE_NAME=$(basename "${RELEASE_PACKAGE}")
    
    ${SSH_CMD} "${DEPLOY_USER}@${DEPLOY_HOST}" << DEPLOY_EOF
set -e

echo "创建部署目录..."
sudo mkdir -p "${DEPLOY_DIR}/${DEPLOY_ENV}"

echo "解压发布包..."
cd "${REMOTE_TMP_DIR}"
tar -xzf "${PACKAGE_NAME}"

RELEASE_DIR=\$(tar -tzf "${PACKAGE_NAME}" | head -1 | cut -f1 -d"/")

echo "复制文件到部署目录..."
sudo cp -r "\${RELEASE_DIR}"/* "${DEPLOY_DIR}/${DEPLOY_ENV}/"

echo "设置权限..."
sudo chmod +x "${DEPLOY_DIR}/${DEPLOY_ENV}/NFPluginLoader" 2>/dev/null || true
sudo chmod +x "${DEPLOY_DIR}/${DEPLOY_ENV}/NFServerController" 2>/dev/null || true

echo "创建日志目录..."
sudo mkdir -p "${DEPLOY_DIR}/${DEPLOY_ENV}/logs"

echo "清理临时文件..."
rm -rf "${REMOTE_TMP_DIR}"

echo "部署完成"
DEPLOY_EOF

    log_success "新版本部署完成"
}

# 启动服务（可选）
start_service() {
    log_info "是否启动服务？(y/n)"
    read -t 10 -n 1 ANSWER || ANSWER="n"
    echo
    
    if [ "${ANSWER}" != "y" ] && [ "${ANSWER}" != "Y" ]; then
        log_warning "跳过启动服务"
        log_info "手动启动命令："
        log_info "  ssh ${DEPLOY_USER}@${DEPLOY_HOST}"
        log_info "  cd ${DEPLOY_DIR}/${DEPLOY_ENV}"
        log_info "  ./NFServerController"
        return
    fi
    
    log_info "启动服务..."
    
    local SSH_CMD="ssh -p ${SSH_PORT}"
    if [ -n "${SSH_KEY}" ]; then
        SSH_CMD="${SSH_CMD} -i ${SSH_KEY}"
    fi
    
    ${SSH_CMD} "${DEPLOY_USER}@${DEPLOY_HOST}" << 'START_EOF'
cd "${DEPLOY_DIR}/${DEPLOY_ENV}"
./NFPluginLoader --Server=AllServer --ID=1.13.1.1 --Config=Config --Plugin=Plugin --Game=${GAME_DIR} --Start --Daemon

sleep 3

# 检查进程
if pgrep -f "NFPluginLoader.*${GAME_DIR}" > /dev/null; then
    echo "服务启动成功"
else
    echo "警告: 服务可能未正常启动"
    exit 1
fi
START_EOF

    log_success "服务启动完成"
}

# 健康检查
health_check() {
    log_info "执行健康检查..."
    
    local SSH_CMD="ssh -p ${SSH_PORT}"
    if [ -n "${SSH_KEY}" ]; then
        SSH_CMD="${SSH_CMD} -i ${SSH_KEY}"
    fi
    
    ${SSH_CMD} "${DEPLOY_USER}@${DEPLOY_HOST}" << 'HEALTH_EOF' || log_warning "健康检查失败"
# 检查进程
if pgrep -f "NFPluginLoader.*${GAME_DIR}" > /dev/null; then
    echo "✓ 进程运行正常"
else
    echo "✗ 进程未运行"
    exit 1
fi

# 检查日志
LOG_DIR="${DEPLOY_DIR}/${DEPLOY_ENV}/logs"
if [ -d "${LOG_DIR}" ]; then
    echo "✓ 日志目录存在"
    
    # 检查最新日志
    LATEST_LOG=$(ls -t ${LOG_DIR}/*.log 2>/dev/null | head -1)
    if [ -n "${LATEST_LOG}" ]; then
        echo "✓ 最新日志: ${LATEST_LOG}"
        echo "最后 10 行日志:"
        tail -10 "${LATEST_LOG}"
    fi
fi

echo "健康检查完成"
HEALTH_EOF

    log_success "健康检查完成"
}

# 回滚到上一个版本
rollback() {
    log_error "部署失败，是否回滚到上一个版本？(y/n)"
    read -t 10 -n 1 ANSWER || ANSWER="n"
    echo
    
    if [ "${ANSWER}" != "y" ] && [ "${ANSWER}" != "Y" ]; then
        log_warning "跳过回滚"
        return
    fi
    
    log_info "回滚到上一个版本..."
    
    local SSH_CMD="ssh -p ${SSH_PORT}"
    if [ -n "${SSH_KEY}" ]; then
        SSH_CMD="${SSH_CMD} -i ${SSH_KEY}"
    fi
    
    ${SSH_CMD} "${DEPLOY_USER}@${DEPLOY_HOST}" << 'ROLLBACK_EOF'
set -e

# 查找最新的备份
LATEST_BACKUP=$(ls -dt "${DEPLOY_DIR}/${DEPLOY_ENV}.backup."* 2>/dev/null | head -1)

if [ -z "${LATEST_BACKUP}" ]; then
    echo "错误: 未找到备份"
    exit 1
fi

echo "回滚到: ${LATEST_BACKUP}"

# 删除当前版本
sudo rm -rf "${DEPLOY_DIR}/${DEPLOY_ENV}"

# 恢复备份
sudo mv "${LATEST_BACKUP}" "${DEPLOY_DIR}/${DEPLOY_ENV}"

echo "回滚完成"
ROLLBACK_EOF

    log_success "回滚完成"
}

# 生成部署报告
generate_deploy_report() {
    local REPORT_FILE="deploy-report-${DEPLOY_ENV}-$(date +%Y%m%d_%H%M%S).txt"
    
    log_info "生成部署报告..."
    
    cat > "${REPORT_FILE}" <<EOF
NFShmXFrame 部署报告
========================================

部署信息:
  环境: ${DEPLOY_ENV}
  主机: ${DEPLOY_HOST}
  用户: ${DEPLOY_USER}
  目录: ${DEPLOY_DIR}/${DEPLOY_ENV}
  项目: ${GAME_DIR}
  版本: ${VERSION}
  部署时间: $(date '+%Y-%m-%d %H:%M:%S')

发布包:
  文件: ${RELEASE_PACKAGE}

部署结果:
  状态: 成功
  备份: ${DEPLOY_DIR}/${DEPLOY_ENV}.backup.*

========================================
EOF

    log_success "部署报告已生成: ${REPORT_FILE}"
}

# 主流程
main() {
    # 检查参数
    check_parameters
    
    # 准备发布包
    prepare_package
    
    # 上传发布包
    upload_package
    
    # 停止现有服务
    stop_service
    
    # 备份现有版本
    backup_current
    
    # 部署新版本
    deploy_new_version || {
        log_error "部署失败"
        rollback
        exit 1
    }
    
    # 启动服务（可选）
    start_service || log_warning "服务启动失败，可能需要手动启动"
    
    # 健康检查
    health_check || log_warning "健康检查未通过，请检查服务状态"
    
    # 生成部署报告
    generate_deploy_report
    
    log_success "=========================================="
    log_success "部署完成！"
    log_success "环境: ${DEPLOY_ENV}"
    log_success "主机: ${DEPLOY_HOST}"
    log_success "目录: ${DEPLOY_DIR}/${DEPLOY_ENV}"
    log_success "=========================================="
}

# 执行主流程
main "$@"

